﻿using ORM.Applicaiton;
using ORM.Model;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ORM.Util
{
    public class MapperBuilder
    {
        private static MapperBuilder _MapperUtil = null;
        private static object MapperUtil_Lock = new object(); //锁同步
        private Dictionary<Type, MapperEntity> MapperDic { set; get; }
        private Dictionary<String, Information_Schema> SchemaDic { set; get; }
        public static MapperBuilder GetInstance()
        {
            if (_MapperUtil == null)
            {
                lock (MapperUtil_Lock)
                {
                    if (_MapperUtil == null)
                    {
                        _MapperUtil = new MapperBuilder();
                    }
                }
            }
            return _MapperUtil;
        }

        public MapperBuilder()
        {
            InitMapperCache();
        }

        private void InitMapperCache()
        {
            //实体类扫描
            MapperDic = new Dictionary<Type, MapperEntity>();
            var baseType = typeof(BaseEntity);
            var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();
            foreach (Assembly assItem in assemblys)
            {
                Type[] typelist = assItem.GetTypes().Where(a => baseType.IsAssignableFrom(a) && a != baseType).ToArray();
                foreach (Type typeItem in typelist)
                {
                    MapperEntity mapperentity = new MapperEntity(typeItem);
                    mapperentity.Init();
                    MapperDic.Add(typeItem, mapperentity);
                }
            }

            //数据库结构表扫描
            DBUtil dbutil = new DBUtil();
            SchemaDic = new Dictionary<String, Information_Schema>();
            StringBuilder databasestr = new StringBuilder();
            ConnectionStringSettingsCollection Conns = System.Configuration.ConfigurationManager.ConnectionStrings;
            foreach (ConnectionStringSettings item in Conns)
            {
                if (item.Name != "LocalSqlServer" && item.Name != "LocalMySqlServer" && !string.IsNullOrEmpty(item.ConnectionString))
                {
                    DataTable tabledt = dbutil.FindView(string.Format("select TABLE_NAME,COLUMN_NAME from information_schema.`COLUMNS` where COLUMN_KEY='PRI' and TABLE_SCHEMA='{0}'", ConfigUtil.GetDataBase(item.Name)), item.Name);
                    Information_Schema info_schema = new Information_Schema();
                    foreach (DataRow row in tabledt.Rows)
                    {
                        info_schema.AddTableMap(Convert.ToString(row["TABLE_NAME"]), Convert.ToString(row["COLUMN_NAME"]));
                    }
                    SchemaDic.Add(item.Name, info_schema);
                }

            }



        }

        public T MapData2Entity<T>(DataRow Row)
        {
            var tp = typeof(T);
            //如果时动态加载dll，这里需要进行判断，没有进行重新生成
            if (!MapperDic.ContainsKey(tp))
            {
                MapperEntity mapperentity = new MapperEntity(tp);
                mapperentity.Init();
                MapperDic.Add(tp, mapperentity);
            }
            MapperEntity mapentity = MapperDic[tp];
            return mapentity.MapInstance<T>(Row);
        }

        public MapperEntity GetMap(Type @Type)
        {
            //如果时动态加载dll，这里需要进行判断，没有进行重新生成
            if (!MapperDic.ContainsKey(@Type))
            {
                MapperEntity mapperentity = new MapperEntity(@Type);
                mapperentity.Init();
                MapperDic.Add(@Type, mapperentity);
            }
            return MapperDic[@Type];
        }

        public string GetSchemaTableKeyFieldName(string ConnectStringName, string TableName)
        {
            return SchemaDic[ConnectStringName].GetKeyFieldName(TableName);
        }
    }
}
